# coding: utf-8
from datetime import datetime
from django.db import models
from django.db.models.functions import Coalesce

from lib.common import BasicManager
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from project.settings import DEFAULT_PAGESIZE
from django.core.exceptions import ObjectDoesNotExist
from services.datamodel.student.models import Student, mm_Student, mm_StudentAgent, mm_StudentTeam
import xlrd
import xlwt
from django.utils import timezone
import json
from django.db import transaction
from apps.student.share import app_logger
from lib.common import CacheKeys
from django.core.cache import cache
from django.db.models import Q, Sum
import random
from io import BytesIO
from django.http import HttpResponse
import os
from lib.esign.run import RunSign
import traceback


class ModelManagerUserCardBatch(BasicManager):

    def get_batch_list(self, page, is_show=None, title=None):
        qs = self.values().order_by("-created_at")
        if is_show:
            qs = qs.filter(is_show=is_show)
        if title:
            qs = qs.filter(title=title)
        paginator = Paginator(qs, 15)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}

        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages}


class ModelManagerUserCards(BasicManager):

    def get_card_list(self, page, batch_id=None, card_number=None, status=None, use_id=None, agent_id=None, id_list=None):
        qs = self.values("card_number", "card_password", "use_student", "use_time", "status", "expired_at",
                         "student__nick_name", "student__mobile", "channel", "role_id",
                         "card_batch").order_by("-created_at")
        if batch_id:
            qs = qs.filter(card_batch_id=batch_id)
        if card_number:
            qs = qs.filter(card_number=card_number)
        if status:
            qs = qs.filter(status=status)
        if use_id:
            qs = qs.filter(use_student=use_id)
        if agent_id:
            qs = qs.filter(student_id=agent_id)
        if id_list:
            qs = qs.filter(id__in=id_list)
        paginator = Paginator(qs, 15)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}

        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages}

    def generate_cards_for_import(self, excel_file, expired_at, user_id=None):
        card_list = []
        sheet = xlrd.open_workbook(file_contents=excel_file.read())
        pass

    def export_agent_cards(self, user_id, nums, role_id, is_app=None, admin_id=None):
         # 显式的开启一个事务
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            # response = None
            # 暴力回滚
            try:
                cards = UserCards.objects.select_for_update().\
                                filter(student_id=user_id, status=0, expired_at__gte=timezone.now(), role_id=role_id).\
                                order_by('expired_at')[:int(nums)]
                if cards.count() < int(nums):
                        return {'retcode': 1, "msg": "余卡不足！"}
                card_list = [i.id for i in cards]
                UserCards.objects.filter(id__in=card_list).update(status=8)
                expiredat = cards[0].expired_at
                res = mm_UserCardLogs.create(
                        seller_student_id=user_id,
                        cards=json.dumps(card_list),
                        buyer_student_id=user_id,
                        nums=nums,
                        channel=7,
                        day=timezone.now().strftime("%Y-%m-%d"),
                        expired_at=expiredat,
                        role_id=role_id,
                        admin_id=admin_id
                    )
                if is_app:
                    res.types = 1
                    res.save()
                    transaction.savepoint_commit(save_id)
                    return {'retcode': 0, "msg": "OK"}
                ws = xlwt.Workbook(encoding="UTF-8")
                w = ws.add_sheet(u'数据')
                w.write(0, 0, u'编号')
                w.write(0, 1, u'卡号')
                w.write(0, 2, u'卡密')
                w.write(0, 3, u'过期时间')
                excel_row = 1
                for obj in cards:
                    w.write(excel_row, 0, obj.id)
                    w.write(excel_row, 1, obj.card_number)
                    w.write(excel_row, 2, str(obj.card_password))
                    w.write(excel_row, 3, obj.expired_at.strftime('%Y-%m-%d %H:%M:%S'))
                    excel_row += 1
                number = random.getrandbits(16*4)
                # ws.save(str(number)+".xls")
                sio = BytesIO()
                ws.save(sio)
                sio.seek(0)
                response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
                response['Content-Disposition'] = 'attachment; filename=stu_info.xls'
                response.write(sio.getvalue())
                return response
            except Exception as e:
                app_logger.error(e)
                transaction.savepoint_rollback(save_id)  # 回滚
            # 提交成功，显式的提交一次事务
            transaction.savepoint_commit(save_id)
        return {'retcode': 0, "msg": "OK"}

    def automatic_paika(self, user_id):
        """
        这是是代理欠下级的卡，等他账号里有卡就自动发放
        :param user_id:
        :return:
        """
        from services.asyntask.paika_task import send_cards
        import collections
        from services.datamodel.setmeal.models import mm_SetMeal
        from apps.student.share import app_logger
        # 这里获取获取他所有的下级代理，逐一发放，直到扣完
        users = mm_StudentTeam.filter(parent_id=user_id, student__level=0).values("student_id",
                                                                                                       "student__level")
        try:
            for vs in users:
                faka_status = cache.get("faka_status_"+str(vs['student_id']))
                if faka_status:
                    datas = cache.get("user_meal_"+str(vs['student_id']))
                    if not datas:
                        continue
                    kaihu = json.loads(datas)
                    meal_dict = mm_SetMeal.get_meal(special_status=1)[kaihu['level']]
                    set_meal_data = collections.defaultdict(list)
                    for v in meal_dict:
                        set_meal_data[v['serial_number']].append({'name': v['name'], 'nums': v['nums'], 'goods_id': v['goods_id']})
                    for v in set_meal_data[kaihu['set_meal']]:
                        user_cards_num_seller = mm_Student.getMyCardStats(kaihu['seller_id'], v['goods_id'])['balance']
                        if user_cards_num_seller is None or user_cards_num_seller < v['nums']:
                            app_logger.error("对不起， 您的余卡不足----这是自动发卡提示")
                            cache.set('card_status_'+str(vs['student_id']), 1, 30)
                    card_status = cache.get('card_status_'+str(vs['student_id']))
                    if not card_status:
                        for v in set_meal_data[kaihu['set_meal']]:
                            send_ret = send_cards(vs['student_id'], v['nums'], None, kaihu['seller_id'], 2,
                                                  level=kaihu['level'], role_id=v['goods_id'],
                                                  seller_level=kaihu['seller_level'])
                            app_logger.error(send_ret)
                        cache.delete("user_meal_"+str(vs['student_id']))
                        cache.delete("faka_status_"+str(vs['student_id']))
                    mm_Student.filter(id=vs['student_id']).update(level=kaihu['level'])
                    mm_Student.get_proxy_cert(mm_Student.get(id=vs['student_id']))
                    mm_UserAuthentication.filter(student_id=vs['student_id'], status=6).update(status=2)
        except:
            err = traceback.format_exc()
            app_logger.error(err)
            return {'retcode': 1, 'msg': "未知错误"}


class ModelManagerUserCardLogs(BasicManager):

    def get_cards_transaction_list(self, page, seller_id=None, buyer_id=None):
        qs = self.values('id', 'seller_student__nick_name', 'buyer_student__nick_name', 'nums', 'day',
                         'channel', 'admin', 'created_at', 'expired_at', 'buyer_student__level',
                         'buyer_student__mobile', 'admin__nick_name', 'role_id', 'seller_student__mobile').\
            order_by("-created_at")
        try:
            if seller_id:
                qs = qs.filter(seller_student_id=seller_id)
            if buyer_id:
                qs = qs.filter(buyer_student_id=buyer_id)
        except ObjectDoesNotExist:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}
        paginator = Paginator(qs, 15)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}
        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages}

    def get_cards_history(self, page, seller_id=None, buyer_id=None, role_id=1, channel=None):
        # qs = self.values('id', 'seller_student__nick_name', 'buyer_student__nick_name', 'nums', 'day',
        #                  'channel', 'admin', 'created_at', 'expired_at',
        #                  'buyer_student__level', 'buyer_student__mobile',
        #                  'admin__nick_name').order_by("-created_at")
        # qs = self.values('id', 'nums', 'channel', 'created_at')
        if seller_id:
            qs = self.filter(~Q(channel=7), ~Q(channel=9), seller_student_id=seller_id, role_id=role_id).values(
                'id', 'nums', 'channel', 'created_at', 'buyer_student__nick_name',
                'buyer_student__avatar').order_by("-id")
            studentid = seller_id
        elif buyer_id:
            qs = self.filter(buyer_student_id=buyer_id, channel__in=[2, 6], role_id=role_id).order_by("-id")
            if channel:
                qs = self.filter(buyer_student_id=buyer_id, channel=7, role_id=role_id).order_by("-id")
            studentid = buyer_id
            qs = qs.values('id', 'nums', 'channel', 'created_at', 'buyer_student__nick_name',
                           'buyer_student__avatar', 'expired_at')

        summary = mm_Student.getMyCardStats(studentid, role_id)
        # print(summary)
        summary['export'] = self.filter(buyer_student_id=studentid, channel=7).aggregate(
            sum=Coalesce(Sum("nums"), 0))['sum']
        # summary['sold'] = summary['total'] - summary['balance']
        summary['sold'] = self.filter(~Q(channel=7), ~Q(channel=9), seller_student_id=studentid, role_id=role_id).aggregate(
            sum=Coalesce(Sum("nums"), 0))['sum']

        paginator = Paginator(qs, DEFAULT_PAGESIZE)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False, 'summary': {'total': 0, 'balance': 0, 'sold': 0}}

        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages, 'summary': summary}

    def export_cards_list(self, page, user_id):
        qs = self.filter(channel=7, buyer_student_id=user_id).filter(created_at__gt='2021-06-10 14:00:00').\
            values("nums", "created_at", "cards", "channel", "types").order_by("-created_at")
        for v in qs:
            if v.get('cards') and v['types'] == 1:
                v['cards'] = list(mm_UserCards.filter(id__in=json.loads(v['cards'])).values("card_number", "card_password"))
            else:
                v['cards'] = []
        paginator = Paginator(qs, 15)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}
        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages}


class ModelManagerUserAuthentication(BasicManager):

    def get_execute_url(self, parent_id, thirdPartyUserId, name, type, company=None, idNo=None, idType=None, mobile=None,
                        posX=300.00, posY=300.00, platform=0):
        """
        发起电签请求----返回任务id
        :param thirdPartyUserId:
        :param name:
        :param type:
        :param company:
        :param idNo:
        :param idType:
        :param mobile:
        :return:
        """
        try:
            parent_user = mm_Student.get_or_default(id=parent_id)
            agent_user = mm_StudentAgent.get_or_default(student_id=parent_id)
            userObj = mm_StudentAgent.get_or_default(student_id=thirdPartyUserId)
            if not userObj:
                return {'retcode': 1, "msg": "被添加代理数据异常"}
            file = mm_AuthenticationTemplate.values('file_id', 'file_name').first()
            result = {}
            if parent_user.level in [7]:
                result = RunSign.createFlowOneStep(file['file_id'], mobile, '杭州扬长文化创意有限公司', file['file_name'],
                                                   type, posX=posX, posY=posY, saccount='13006090917', platform=platform)
            signerAccount = ''
            if parent_user.level in [1, 2, 3, 4]:
                signerAccount = parent_user.mobile
                # 这里有个特殊的情况，就是区代是用上级的资质来盖章
                if parent_user.level in [3, 4]:
                    # 首先考虑该1区代有没有上级
                    parents = mm_Student.getDirectProxy(parent_user.id)
                    if not parents:
                        result = RunSign.createFlowOneStep(file['file_id'], mobile, '杭州扬长文化创意有限公司', file['file_name'],
                                                           1, posX=posX, posY=posY, saccount='13006090917',
                                                           platform=platform)
                    else:
                        parents_agent = mm_StudentAgent.get_or_default(student_id=parents.id)
                        result = RunSign.createFlowOneStep(file['file_id'], mobile, parents_agent.name, file['file_name'],
                                                           2, posX=posX, posY=posY, saccount=signerAccount,
                                                           platform=platform)

                else:
                    result = RunSign.createFlowOneStep(file['file_id'], mobile, agent_user.name, file['file_name'],
                                                       type, posX=posX, posY=posY, saccount=signerAccount,
                                                       platform=platform)
            app_logger.error(result)
            if result['code'] != 0:
                return {'retcode': 1, "msg": result['message']}
            res = {}
            if parent_user.level in [1, 2, 3, 4]:
                if parent_user.level in [3, 4]:
                    if not parents:
                        res = RunSign.getExecuteUrl(flowId=result['data']['flowId'], authorizedAccount='杭州扬长文化创意有限公司',
                                                    signerAccount=signerAccount, platform=platform, types=2)
                    else:
                        parents_agent = mm_StudentAgent.get_or_default(student_id=parents.id)
                        res = RunSign.getExecuteUrl(flowId=result['data']['flowId'], authorizedAccount=parents_agent.name,
                                                    signerAccount=signerAccount, platform=platform, types=2)
                else:
                    res = RunSign.getExecuteUrl(flowId=result['data']['flowId'], authorizedAccount=agent_user.name,
                                                signerAccount=signerAccount, platform=platform, types=2)
                if res['code']:
                    return {'retcode': 1, "msg": res['message']}
            # 合同id存储
            self.create(
                parent_id=parent_id,
                student_id=userObj.student_id,
                flow_id=result['data']['flowId'],
                status=0,
                url=res['data']['url'] if res else ''
            )
            return {'retcode': 0, "msg": "ok", "data": res['data']['url'] if res else ''}
        except:
            err = traceback.format_exc()
            app_logger.error(err)
            return {'retcode': 1, "msg": "数据异常"}

    def set_authentication(self, user_id, platform=0):
        """
        实名账号认证
        :param user_id:
        :return:
        """
        try:
            userObj = mm_StudentAgent.filter(student_id=user_id, status=0).values("status", "student__level",
                                                                                  "account_id", "org_id", "student_id",
                                                                                  "student__mobile", "name").first()
            notify_url = 'http://prod.momself.cn/api/esign/oauth2/notify'
            redirect_url = ''
            if userObj:
                cache_data = cache.get("user_meal_"+str(userObj['student_id']))
                result = {}
                if userObj['student__level'] in [1, 2]:
                    result = RunSign.oauth2(redirectUrl=redirect_url, notifyUrl=notify_url, bizType='combination',
                                            state=user_id, account=userObj['student__mobile'], platform=platform,
                                            name=userObj['name'])
                if cache_data:
                    user_agent_data = json.loads(cache_data)
                    if user_agent_data['level'] in [3, 4, 5, 6]:
                        result = RunSign.oauth2(redirectUrl=redirect_url, notifyUrl=notify_url, bizType='authentication',
                                                state=user_id, account=userObj['student__mobile'], platform=platform,
                                                level=user_agent_data['level'])
                if userObj['student__level'] in [3]:
                    result = RunSign.oauth2(redirectUrl=redirect_url, notifyUrl=notify_url, bizType='authentication',
                                            state=user_id, account=userObj['student__mobile'], platform=platform,
                                            level=userObj['student__level'])
                app_logger.error(result)
                if result['code'] != 0:
                    return {'retcode': 1, "msg": result['message']}
                return {'retcode': 0, "data": result['data'], "msg": "OK"}
            else:
                return {'retcode': 1, "msg": "该用户还未开户或已经实名认证"}
        except:
            err = traceback.format_exc()
            app_logger.error(err)
            return {'retcode': 1, "msg": "数据异常"}

    def get_contract(self, user_id, platform=0):
        """
        从数据库中获取实名认证url
        :param user_id:
        :return:
        """
        resObj = mm_StudentAgent.get_or_default(student_id=user_id)
        if not resObj:
            return {'retcode': 1, "msg": "不是代理,请先申请代理"}
        authentication = mm_UserAuthentication.filter(student_id=user_id, status=1).values().first()
        if not authentication:
            return {'retcode': 1, 'msg': '数据异常,不存在认证合同'}
        types = 0
        cache_data = cache.get("user_meal_"+str(resObj.student_id))
        user_agent_data = json.loads(cache_data)
        if resObj.student.level in [1, 2, 3]:
            types = 2
        if user_agent_data['level'] in [4, 5, 6]:
            types =1
        res = RunSign.getExecuteUrl(flowId=authentication['flow_id'], signerAccount=resObj.student.mobile,
                                    platform=platform, types=types)
        return {'retcode': 0, "msg": "OK", 'data': res['data']['url']}

    def contract_list(self, page, parent=None, user=None, status=None, p_id=None):
        qs = self.values("flow_id", "created_at", "status", "url", "contract", "parent_id", "updated_at",
                         "student_id", "parent__level", "student__nick_name", "parent__provincename",
                         "parent__cityname", "parent__districtname", "id", "parent__nick_name").order_by("-id")
        if parent:
            parentObj = mm_StudentAgent.get_or_default(username=parent)
            if not parentObj:
                return {'retlist': [], 'curpageidx': page,
                        'hasnext': False, 'hasprevious': False}
            qs = qs.filter(student_id=parentObj.student_id)
        if user:
            userObj = mm_StudentAgent.get_or_default(username=user)
            if not userObj:
                return {'retlist': [], 'curpageidx': page,
                        'hasnext': False, 'hasprevious': False}
            qs = qs.filter(student_id=userObj.student_id)
        if status:
            if int(status) == 1:
                qs = qs.filter(status__in=[0, 1])
            else:
                qs = qs.filter(status=2)
        if p_id:
            qs = qs.filter(parent_id=p_id)
        paginator = Paginator(qs, 15)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}
        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages}

    def authorizer_info(self, uid):
        """
        查询个人实名状态
        :param uid:
        :return:
        """
        user = mm_Student.get_or_default(id=uid)
        result = RunSign.authorizerInfo(mobile=user.mobile)
        return result

    def organizations(self, uid):
        """
        查询组织机构实名状态
        :param uid:
        :return:
        """
        user = mm_StudentAgent.get_or_default(student_id=uid)
        result = RunSign.organizations(name=user.name)
        return result


class ModelManagerAuthenticationTemplate(BasicManager):

    def create_template(self, name, path, types=1, file_name=None):
        """
        创建模板
        :param name:
        :param path:
        :param types:
        :param file_name:
        :return:
        """
        try:
            res = self.create(
                name=name,
                types=types,
                file_name='1',
            )
            result = RunSign.uploadFile(path)
            res.file_id = result['data']['fileId']
            res.file_url = result['data']['uploadUrl']
            res.save()
            return {'retcode': 0, "msg": "OK"}
        except Exception as e:
            app_logger.error(e)
            return {'retcode': 1, "msg": e}

    def update_template(self, id, name, path, types=1, file_name=None):
        try:
            res = self.get_or_default(id=id)
            res.name = name
            if path:
                result = RunSign.uploadFile(path)
                res.file_id = result['data']['fileId']
                res.file_url = result['data']['uploadUrl']
            res.save()
            return {'retcode': 0, "msg": "OK"}
        except Exception as e:
            app_logger.error(e)
            return {'retcode': 1, "msg": e}

    def template_list(self, page):
        qs = self.values("name", "file_name", "id", "file_url")
        paginator = Paginator(qs, 10)
        try:
            result_page = paginator.page(page)
        except PageNotAnInteger:
            result_page = paginator.page(1)
        except EmptyPage:
            return {'retlist': [], 'curpageidx': page,
                    'hasnext': False, 'hasprevious': False}
        return {'retlist': list(result_page), 'curpageidx': page,
                'hasnext': result_page.has_next(), 'hasprevious': result_page.has_previous(),
                'total_page': paginator.num_pages}


class UserCardBatch(models.Model):
    sort = models.IntegerField("排序", default=0)
    role_id = models.IntegerField('', default=0)
    title = models.CharField("标题", max_length=100)
    total_num = models.IntegerField("生成卡数量", default=0)
    use_num = models.IntegerField("使用数量", default=0)
    created_at = models.DateTimeField("添加时间", auto_now_add=True)
    updated_at = models.DateTimeField("修改时间", auto_now=True)

    objects = ModelManagerUserCardBatch()

    class Meta:
        verbose_name = ''
        verbose_name_plural = verbose_name
        db_table = "momself_user_card_batch"

    def __str__(self):
        return self.title


class UserCards(models.Model):
    card_batch = models.ForeignKey(UserCardBatch, verbose_name="UserCardBatc表ID", related_name="card_batch")
    card_number = models.CharField("卡号", max_length=50)
    card_password = models.CharField("卡密", max_length=30)
    use_student = models.IntegerField("使用者用户", default=0)
    use_time = models.DateTimeField("使用时间", null=True)
    status = models.PositiveSmallIntegerField("卡状态", default=0)  # 卡状态：0：未使用；1：激活；8：导出（线下使用）
    student = models.ForeignKey(Student, default=1)  # 囤卡用户
    expired_at = models.DateTimeField("过期时间", null=True)
    channel = models.PositiveSmallIntegerField("渠道", default=0)  # channel=1上级补卡所得 2:上级开户所得  3:导入
    created_at = models.DateTimeField("添加时间", auto_now_add=True)
    updated_at = models.DateTimeField("修改时间", auto_now=True)
    role_id = models.IntegerField("vip主键id")

    objects = ModelManagerUserCards()

    class Meta:
        verbose_name = ''
        verbose_name_plural = verbose_name
        db_table = "momself_user_cards"
        index_together = ["student", "expired_at", "status"]


class UserCardLogs(models.Model):
    """
    从buyer角度增加这个表的记录
    """
    seller_student = models.ForeignKey(Student)  # 卖家：1:系统   其他代理id
    cards = models.TextField("卡的主键ID", default='')  # ['id1']
    types = models.PositiveSmallIntegerField("类型", default=0)  # 导出区分  区分是代言人自己导出还是后台导出  1:是代言人自己
    # 1:卖出去，目前用不到  2:（补卡，派卡）  3:赠送（暂无） 4:消费（线上付钱或激活）, 5:第三方导入， 6：开户
    buyer_student = models.ForeignKey(Student, related_name="buyer_student")
    nums = models.IntegerField("数量", default=0)
    day = models.DateField("日期")
    channel = models.PositiveSmallIntegerField("渠道", default=0)
    # 1:卖出去，目前用不到  2:（补卡，派卡）  3:赠送（暂无） 4:消费, 5:第三方导入， 6：开户， 7：导出, 8: 激活, 9: 导出后激活
    # wni： 这是删除types之前的注释 channel=1上级补卡/派卡所得或app上购买 2:上级开户所得  3:导入
    expired_at = models.DateTimeField("过期时间", null=True)
    admin = models.ForeignKey(Student, related_name="admin_student", null=True)
    role_id = models.IntegerField("vip主键id")
    created_at = models.DateTimeField("添加时间", auto_now_add=True)
    updated_at = models.DateTimeField("修改时间", auto_now=True)

    objects = ModelManagerUserCardLogs()

    class Meta:
        verbose_name = ''
        verbose_name_plural = verbose_name
        db_table = "momself_user_card_logs"
        index_together = (("seller_student", "channel"), ("buyer_student", "channel"))


class UserAuthentication(models.Model):
    """
    易签宝发起记录
    """
    parent = models.ForeignKey(Student, related_name='parent')  # 开户人
    student = models.ForeignKey(Student)  # 发起用户
    flow_id = models.CharField("任务id", max_length=100)
    status = models.PositiveSmallIntegerField("任务状态", default=0)  # 0代表进行中， 1代表待成功  2代表成功
    url = models.TextField("签署地址", default='', blank=True)
    contract = models.TextField("合同地址", default='', blank=True)
    created_at = models.DateTimeField("添加时间", auto_now_add=True)
    updated_at = models.DateTimeField("修改时间", auto_now=True)

    objects = ModelManagerUserAuthentication()

    class Meta:
        verbose_name = ''
        verbose_name_plural = verbose_name
        db_table = "momself_user_authentication"


class AuthenticationTemplate(models.Model):
    name = models.CharField("合同名称", max_length=50)
    file_id = models.CharField("第三方文件id", max_length=100, default='', blank=True)
    file_url = models.CharField("第三方文件id", max_length=200, default='', blank=True)
    types = models.PositiveSmallIntegerField("合同类型", default=1)
    file_name = models.CharField("文件名称", max_length=50, default='', blank=True)
    created_at = models.DateTimeField("添加时间", auto_now_add=True)
    updated_at = models.DateTimeField("修改时间", auto_now=True)

    objects = ModelManagerAuthenticationTemplate()

    class Meta:
        verbose_name = ''
        verbose_name_plural = verbose_name
        db_table = "momself_user_authentication_template"


mm_UserCards = UserCards.objects
mm_UserCardBatch = UserCardBatch.objects
mm_UserCardLogs = UserCardLogs.objects
mm_UserAuthentication = UserAuthentication.objects
mm_AuthenticationTemplate = AuthenticationTemplate.objects
